Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

227
Vistas
does angular have the "computed property" feature like in vue.js?

I learnt Vue.js first, and now have a project in Angular 4 so I just learnt Angular. I find everything is not that different from Vue except the "Computed Property". In Vue, I can create a computed property that listens to changes of other properties and run calculations automatically.

For example(in Vue 2):

computed: {
    name(){
        return this.firstname + ' ' + this.lastname;
    }
}

The name property will only recalculate when one of firstname or lastname change. How to handle this in Angular 2 or 4 ?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

While this is already answered but I think this is not very good answer and users should not use getters as computed properties in angular. Why you may ask? getter is just sugar syntax for function and it will be compiled to plain function, this means that it will be executed on every change detection check. This is terrible for performance because property is recomputed hundred of times on any change.

Take a look at this example: https://plnkr.co/edit/TQMQFb?p=preview

@Component({
    selector: 'cities-page',
    template: `
        <label>Angular computed properties are bad</label>

        <ng-select [items]="cities"
                   bindLabel="name"
                   bindValue="id"
                   placeholder="Select city"
                   [(ngModel)]="selectedCityId">
        </ng-select>
        <p *ngIf="hasSelectedCity">
            Selected city ID: {{selectedCityId}}
        </p>
        <p><b>hasSelectedCity</b> is recomputed <b [ngStyle]="{'font-size': calls + 'px'}">{{calls}}</b> times</p>
    `
})
export class CitiesPageComponent {
    cities: NgOption[] = [
        {id: 1, name: 'Vilnius'},
        {id: 2, name: 'Kaunas'},
        {id: 3, name: 'Pabradė'}
    ];
    selectedCityId: any;

    calls = 0;

    get hasSelectedCity() {
      console.log('hasSelectedCity is called', this.calls);
      this.calls++;
      return !!this.selectedCityId;
    }
}

If you really want to have computed properties you can use state container like mobx

class TodoList {
    @observable todos = [];
    @computed get unfinishedTodoCount() {
        return this.todos.filter(todo => !todo.finished).length;
    }
}

mobx has @computed decorator so getter property will be cached and recalculated only when needed

over 4 years ago · Santiago Trujillo Denunciar

0

I will try to improve upon Andzej Maciusovic's hoping to obtain a canonical answer. Indeed VueJS has a feature called computed property that can be quickly shown using an example:

<template>
  <div>
    <p>A = <input type="number" v-model="a"/></p>
    <p>B = <input type="number" v-model="b"/></p>
    <p>C = <input type="number" v-model="c"/></p>
    <p>Computed property result: {{ product }}</p>
    <p>Function result: {{ productFunc() }}</p>
  </div>
</template>

<script>
export default {
  data () {
    return {
      a: 2,
      b: 3,
      c: 4
    }
  },

  computed: {
    product: function() {
      console.log("Product called!");
      return this.a * this.b;
    }
  },

  methods: {
    productFunc: function() {
      console.log("ProductFunc called!");
      return this.a * this.b;
    }
  }
}
</script>

Whenever the user changes input value for a or b, both product and productFunc are logging to console. If user changes c, only productFunc is called.

Coming back to Angular, mobxjs really helps with this issue:

  1. Install it using npm install --save mobx-angular mobx
  2. Use observable and computed attributes for bound properties

TS file

    import { observable, computed } from 'mobx-angular';

    @Component({
       selector: 'home',
       templateUrl: './home.component.html',
       animations: [slideInDownAnimation]
    })
    export class HomeComponent extends GenericAnimationContainer {
       @observable a: number = 2;
       @observable b: number = 3;
       @observable c: number = 4;

       getAB = () => {
           console.log("getAB called");
           return this.a * this.b;
       }

       @computed get AB() {
           console.log("AB called");
           return this.a * this.b;
       }
    }

Markup

<div *mobxAutorun>
    <p>A = <input type="number" [(ngModel)]="a" /> </p>
    <p>B = <input type="number" [(ngModel)]="b" /> </p>
    <p>C = <input type="number" [(ngModel)]="c" /> </p>
    <p> A * B = {{ getAB() }}</p>
    <p> A * B (get) = {{ AB }}</p>
</div>

If a or b is changed, AB is called once and getAB several times. If c is changed, only getAB is called. So, this solution is more efficient even when computation must be performed.

over 4 years ago · Santiago Trujillo Denunciar

0

In some cases using a Pure Pipe might be a reasonable alternative, obviously that comes with some restrictions but it at least avoids the costliness of executing the function on any event.

@Pipe({ name: 'join' })
export class JoinPipe implements PipeTransform {
  transform(separator: string, ...strings: string[]) {
    return strings.join(separator);
  }
}

In your template instead of a full name property you might be able to instead just use ' ' | join:firstname:lastname. Pretty sad that computed properties still don't exist for angular.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda